package com.xipu.yygh.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xipu.yygh.common.exception.YyghException;
import com.xipu.yygh.common.utils.JwtHelper;
import com.xipu.yygh.enums.AuthStatusEnum;
import com.xipu.yygh.model.user.Patient;
import com.xipu.yygh.model.user.UserInfo;
import com.xipu.yygh.user.mapper.UserInfoMapper;
import com.xipu.yygh.user.service.PatientService;
import com.xipu.yygh.user.service.UserInfoService;
import com.xipu.yygh.vo.user.LoginVo;
import com.xipu.yygh.vo.user.UserAuthVo;
import com.xipu.yygh.vo.user.UserInfoQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author gql
 * @since 2022-05-05
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    /**
     * RedisTemplate
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 就诊人表
     */
    @Autowired
    private PatientService patientService;

    @Override
    public Map<String, Object> userLogin(LoginVo loginVo) {
        // 1.校验手机号和验证码
        if (StringUtils.isEmpty(loginVo.getPhone()) || StringUtils.isEmpty(loginVo.getCode())) {
            throw new YyghException(20001, "手机号或验证码为空");
        }

        // 2.验证码校验
        if (loginVo.getCode().equals(this.redisTemplate.opsForValue().get(loginVo.getCode()))) {
            throw new YyghException(20001, "验证码校验失败");
        }

        // 3.如果是手机验证码登录
        if (StringUtils.isEmpty(loginVo.getOpenid())) {
            UserInfo userInfo = this.baseMapper.selectOne(
                    Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getPhone, loginVo.getPhone()));
            if (StringUtils.isEmpty(userInfo)) {
                userInfo = new UserInfo();
                userInfo.setPhone(loginVo.getPhone());
                userInfo.setStatus(1);
                this.baseMapper.insert(userInfo);
            } else {
                if (userInfo.getStatus() == 0) {
                    throw new YyghException(20001, "此用户状态为停用,请联系管理员");
                }
            }
            return getNameAndToken(userInfo);
        }

        // 4.如果是微信登录,需要绑定手机号
        UserInfo userInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getPhone, loginVo.getPhone()));
        if (StringUtils.isEmpty(userInfo)) {
            // 微信第一次绑定手机号
            UserInfo tempUserInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getOpenid, loginVo.getOpenid()));
            if (StringUtils.isEmpty(tempUserInfo)) {
                throw new YyghException(20001, "此微信信息不存在");
            }
            tempUserInfo.setPhone(loginVo.getPhone());
            this.baseMapper.updateById(tempUserInfo);
            return getNameAndToken(tempUserInfo);
        } else {
            // 表中存在相同手机号,将手机号登录过的数据,更新到微信中
            UserInfo tempUserInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getOpenid, loginVo.getOpenid()));
            tempUserInfo.setPhone(userInfo.getPhone());
            tempUserInfo.setName(userInfo.getName());
            tempUserInfo.setCertificatesType(userInfo.getCertificatesType());
            tempUserInfo.setCertificatesNo(userInfo.getCertificatesNo());
            tempUserInfo.setCertificatesUrl(userInfo.getCertificatesUrl());
            this.baseMapper.delete(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getPhone, loginVo.getPhone()));
            System.out.println("tempUserInfo.getPhone() = " + tempUserInfo.getPhone());
            this.baseMapper.updateById(tempUserInfo);
            return getNameAndToken(tempUserInfo);
        }
    }

    /**
     * 获取姓名和Token
     * @param userInfo 用户信息
     * @return map
     */
    private HashMap<String, Object> getNameAndToken(UserInfo userInfo) {
        HashMap<String, Object> map = new HashMap<>();
        // 1.优先显示姓名
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)) {
            // 如果姓名为空,就显示昵称
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            // 如果昵称为空就显示手机号
            name = userInfo.getPhone();
        }
        map.put("name", name);
        map.put("token", JwtHelper.createToken(userInfo.getId(), userInfo.getName()));
        return map;
    }

    @Override
    public UserInfo getUserInfoByOpenId(String openid) {
        return this.baseMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getOpenid, openid));
    }

    @Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        UserInfo userInfo = this.baseMapper.selectById(userId);
        if (StringUtils.isEmpty(userInfo)) {
            throw new YyghException(20001, "用户信息不存在!");
        } else {
            // 设置认证信息
            userInfo.setName(userAuthVo.getName());// 认证人姓名
            userInfo.setCertificatesType(userAuthVo.getCertificatesType());
            userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
            userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
            userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
            baseMapper.updateById(userInfo);
        }
    }

    @Override
    public IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo userInfoQueryVo) {
        // 1.获取条件值
        String name = userInfoQueryVo.getKeyword();
        Integer status = userInfoQueryVo.getStatus();
        Integer authStatus = userInfoQueryVo.getAuthStatus();
        String createTimeBegin = userInfoQueryVo.getCreateTimeBegin();
        String createTimeEnd = userInfoQueryVo.getCreateTimeEnd();
        // 2.判断条件值是否为空,不为空就封装条件
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(name)) {
            wrapper.like("name", name);
        }
        if (!StringUtils.isEmpty(status)) {
            wrapper.eq("status", status);
        }
        if (!StringUtils.isEmpty(authStatus)) {
            wrapper.eq("auth_status", authStatus);
        }
        if (!StringUtils.isEmpty(createTimeBegin)) {
            wrapper.ge("create_time", createTimeBegin);
        }
        if (!StringUtils.isEmpty(createTimeEnd)) {
            wrapper.le("create_time", createTimeEnd);
        }
        // 3.调用mapper的方法
        IPage<UserInfo> pages = baseMapper.selectPage(pageParam, wrapper);
        //编号变成对应值封装
        pages.getRecords().forEach(this::packageUserInfo);
        return pages;
    }

    @Override
    public void lock(Long userId, Integer status) {
        if (status == 0 || status == 1) {
            UserInfo userInfo = this.getById(userId);
            userInfo.setStatus(status);
            this.updateById(userInfo);
        }
    }

    @Override
    public Map<String, Object> showUser(Long userId) {
        // 1.查询用户信息并封装
        UserInfo userInfo = baseMapper.selectById(userId);
        this.packageUserInfo(userInfo);
        // 2.查询用户下的就诊人列表
        List<Patient> list = this.patientService.findAllPatient(userId);
        // 3.返回到前端的map集合中
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", userInfo);
        map.put("patientList", list);
        return map;
    }

    @Override
    public void approval(Long userId, Integer authStatus) {
        if (authStatus == 2 || authStatus == -1) {
            UserInfo userInfo = baseMapper.selectById(userId);
            userInfo.setAuthStatus(authStatus);
            baseMapper.updateById(userInfo);
        }
    }

    /**
     * 用户状态变成对应值封装
     * @param userInfo 用户信息
     */
    private void packageUserInfo(UserInfo userInfo) {
        //处理认证状态编码
        userInfo.getParam().put("authStatus", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
        //处理用户状态 0  1
        String status = userInfo.getStatus() == 0 ? "锁定" : "正常";
        userInfo.getParam().put("status", status);
    }

}
